package com.topdt.jbpm.form;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.thx.common.spring.BeanFactory;
import com.thx.common.util.ObjectUtils;
import com.thx.common.util.ThreadLocalContext;
import com.topdt.jbpm.Constants;
import com.topdt.jbpm.identity.User;
import com.topdt.jbpm.model.Application;
import com.topdt.jbpm.model.Control;
import com.topdt.jbpm.model.Form;
import com.topdt.jbpm.model.Work;
import com.topdt.jbpm.model.WorkOpinion;
import com.topdt.jbpm.service.CommentService;
import com.topdt.jbpm.service.ControlService;
import com.topdt.jbpm.utils.ControlUtils;


/**
 *  @Project       : saasoa
 *  @Program Name  : com.topdt.jbpm.form.CustomFormHandle.java
 *  @Class Name    : CustomFromHandle
 *  @Description   : 抽象自定义表单处理
 *  @Author        : calonlan
 *  @Creation Date : 2015年3月9日 上午11:58:53
 *  @ModificationHistory
 *  Who        When          What
 *  --------   ----------    -----------------------------------
 *  username   2015年3月9日       TODO
 */
public abstract class AbstractCustomFormHandle extends AbstractFormHandle{

	@Override
	public FormUI assemble(Map<String, Object> context) {
		Application app=(Application)context.get("appObj");
		User user = (User)context.get("userObj");
		context.put("currentUserName", user.getName());
		context.put("sessionId",(String)ThreadLocalContext.get(Constants.SESSIONID_KEY));
		context.put("appName", app.getAppName());
		String appAttr = app.getAppAttr();
		if(Application.APPATTR_CUSTOM_DOC.equals(appAttr) || Application.APPATTR_CUSTOM_DOC_OPINION.equals(appAttr))
			context.put("body", "");
		Work work = (Work)context.get("workObj");

		if(work.isFreeFlow())
			context.put("freeFlow", "true");
		//?
		Form form = app.getForm();

		Document doc = getDocument(work.getWorkId());
		//获取权限控制对象
		ControlService controlService = (ControlService) BeanFactory.getBean("controlService");

		String activity=(String)context.get("activity");
		Object[] objs = new Object[] { app.getAppId(), work.getFlowId(), activity, form.getFormId() };
		Control control = controlService.getControlByObjects(objs);

		if (control == null) {
			//预览设置意见
			if(Application.APPATTR_CUSTOM_FORM_OPINION.equals(appAttr)
					|| Application.APPATTR_CUSTOM_DOC_OPINION.equals(appAttr)) {
				setReadonlyOpinions(app, context, work);
			}
			return getFormUI(app, null, null, doc,context,work);
		}

		Map<String, String> fieldControl = new HashMap<String, String>();
		java.lang.reflect.Field[] fields = doc.getClass().getDeclaredFields();

		if(fields==null || fields.length <= 0)
			return getFormUI(app, null, null, null,context,work);

		//将字段和字段权限的对应关系放到权限控制map
		//已"fp_"开始，已非"_name"结束的字符串
		Pattern p = Pattern.compile("^(fp_).*(?<!_name)$");
		int index = 0;
		for (int i=0; i<fields.length; i++) {
			java.lang.reflect.Field field = fields[i];
			//过滤没有加入权限控制的字段
			Matcher m = p.matcher(field.getName());
			if(m.find()) {
				fieldControl.put(field.getName(), String.valueOf(control.getFieldControl().charAt(index)));
				index++;
			}
		}
		if (fieldControl.size() == 0)
			fieldControl = null;

		//将流程环节操作权限放到权限控制map
		Map<String, String> funControl = new HashMap<String, String>();
		String[][] menuItems = FormMenuDefin.getMenuItems(app.getAppAttr());

		//
		for (int i = 0; i < menuItems.length; i++) {
			String[] item = menuItems[i];
			//weboffice编辑文档的按钮控制
			if(item[1].equals("编辑正文")) {
				context.put("docControl", control.getFunctionControl().substring(i));
			}
			funControl.put(item[0], String.valueOf(control.getFunctionControl().charAt(i)));
		}
		if (funControl.size() == 0)
			funControl = null;

		//整合外置意见以及意见权限
		if(Application.APPATTR_CUSTOM_FORM_OPINION.equals(appAttr)
				|| Application.APPATTR_CUSTOM_DOC_OPINION.equals(appAttr)) {
			setOpinionsAndAuthority(app, context, work, control);
		}

		return getFormUI(app, fieldControl, funControl, doc,context, work);
	}


	/**
	 *  @Description    : 获取表单字段权限(读写性)
	 *  @Method_Name    : getFieldAuthorityContext
	 *  @param app
	 *  @param fieldControl
	 *  @param doc
	 *  @param context
	 *  @param work
	 *  @return
	 *  @Creation Date  : 2015年3月10日 下午6:51:55
	 *  @version        : v1.00
	 *  @Author         : calonlan
	 *  @Update Date    : 2015年3月10日 下午6:51:55
	 *  @Update Author  : calonlan
	 */
	@Override
	protected Map<String, Object> getFieldAuthorityContext(Application app, Map<String, String> fieldControl,
			Document doc, Map<String, Object> context, Work work) {
		//字段控制
		java.lang.reflect.Field[] fields = doc.getClass().getDeclaredFields();
		if (fields != null && fields.length > 0) {
			//已"fp_"开始，已非"_name"结束的字符串
			Pattern p = Pattern.compile("^(fp_).*(?<!_name)$");
			for (java.lang.reflect.Field field : fields) {
				String fieldName = field.getName();
				//过滤没有加入权限控制的字段
				Matcher m = p.matcher(field.getName());
				if(m.find()) {
					Map att = new HashMap();
					if (fieldControl != null && fieldControl.size() > 0) {
						//该字段是否是只读
						if (ControlUtils.getReadValue(fieldControl.get(fieldName))) {
							att.put("readonly", "readonly");
						}
						//该字段是否显示(在html)
						if (!ControlUtils.getShowValue(fieldControl.get(fieldName))) {
							att.put("show", "display:none");
						}
					} else {
						//没有控制时 默认起草时为可编辑,其它节点为只读
						if (!work.getWorkState().equals(Work.STATE_START)) {
							att.put("readonly", "readonly");
						}
					}
					context.put(fieldName, att);
				}

				SysParamService sysParamService = (SysParamService) BeanFactory.getBean(SysParamService.class);
				/*if (value != null && value.size() > 0 && value.get(fieldName) != null) {
				 	//如果是预览
					if(context.get("isView")!=null&&(Boolean)context.get("isView")){
						if("radio".equals(field.getFieldType())||"checkbox".equals(field.getFieldType())
								||"select".equals(field.getFieldType())){
								Option option =sysParamService.getOptionName( (String) value.get(fieldName), "more");
								att.put("text",option.getName());
							}else if("tree".equals(field.getFieldType())){
								Option option =sysParamService.getOptionName( (String) value.get(fieldName), "tree");
								att.put("text",option.getName());
							}else {
								att.put("value", value.get(fieldName));
							}
					}else{
						if(context.get("isMobile")!=null&&(Boolean)context.get("isMobile")&&"richTextEditer".equals(field.getFieldType())){
									String  richTextvalue = (String) value.get(fieldName);
									richTextvalue =Jsoup.clean(richTextvalue, Whitelist.none());
									att.put("value", richTextvalue);
						}else{
							att.put("value", value.get(fieldName));
						}
					}

				}
				if ("systemVar".equals(field.getFieldType())) {
						Option option  = sysParamService.getOptionName(field.getFieldOption(), "system");
						context.put(option.getValue(),SystemVarEval.getValue(field.getFieldOption()));
				}*/
			}
		}
		return context;
	}


	/**
	 *  @Description    : 把外置意见数据和权限放到context中
	 *  @param app
	 *  @param context
	 *  @param work
	 *  @param ctrl
	 *  @return         : void
	 *  @version        : v1.00
	 */
	private void setOpinionsAndAuthority(Application app, Map<String, Object> context, Work work, Control ctrl) {
		String formClassName = app.getAppForm().getFormJava();
		Object opinionObj = ObjectUtils.getInstance(formClassName+"Opinion");
		java.lang.reflect.Field [] fields = opinionObj.getClass().getDeclaredFields();
		Map<String, Boolean> att = null;
		CommentService commentService = (CommentService) BeanFactory.getBean(CommentService.class);
		//客户端是否填写意见标识，默认不填写意见
		context.put("isOpinion", "none");
		for(Field field : fields) {
			String fieldName = field.getName();

			if(!fieldName.contains("_name")) {
				//设置意见权限
				att = new HashMap<String, Boolean>();
				if(fieldName.equals(ctrl.getOpinionName())) {
					att.put("isRead", false);
					context.put("isOpinion", "");
				} else {
					att.put("isRead", true);
				}
				context.put(fieldName, att);

				//设置意见数据
				List<WorkOpinion> list = commentService.findByOpinionName(fieldName,
						work.getAppId(), work.getFlowId(), work.getWorkId());
				context.put(fieldName+"OpinionList", list);
			}

		}
	}


	/**
	 *  @Description    : 只读的外置意见
	 *  @param app
	 *  @param context
	 *  @param work
	 *  @return         : void
	 *  @version        : v1.00
	 */
	private void setReadonlyOpinions(Application app, Map<String, Object> context, Work work) {
		String formClassName = app.getAppForm().getFormJava();
		Object opinionObj = ObjectUtils.getInstance(formClassName+"Opinion");
		java.lang.reflect.Field [] fields = opinionObj.getClass().getDeclaredFields();
		Map<String, Boolean> att = null;
		CommentService commentService = (CommentService) BeanFactory.getBean(CommentService.class);
		for(Field field : fields) {
			String fieldName = field.getName();
			if(!fieldName.contains("_name")) {
				//设置意见权限
				att = new HashMap<String, Boolean>();
				att.put("isRead", true);
				context.put(fieldName, att);
				//设置意见数据
				List<WorkOpinion> list = commentService.findByOpinionName(fieldName,
						work.getAppId(), work.getFlowId(), work.getWorkId());
				context.put(fieldName+"OpinionList", list);
			}

		}
		//意见只读
		context.put("isOpinion", "none");
	}


}
